﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using UtilZ.Dotnet.Ex.Model;

namespace UtilZ.Dotnet.Ex.Communication.Net.Web
{
    /// <summary>
    /// http响应类
    /// </summary>
    public partial class HttpResponse : IHttpResponse
    {
        //HTTP响应报文主要由状态行、响应头部、响应正文3部分组成

        /// <summary>
        /// http协议版本
        /// </summary>
        public string HttpProtocolVer { get; set; } = WebConstnats.HTTP_PROTOCOL_VER;

        /// <summary>
        /// http响应状态值
        /// </summary>
        public int StatusCode { get; set; } = HttpStatusCodes.OK;


        private readonly HttpConnection _connection;
        /// <summary>
        /// http连接
        /// </summary>
        public HttpConnection Connection
        {
            get { return _connection; }
        }


        private readonly Dictionary<string, string> _headers;
        /// <summary>
        /// 响应头部
        /// </summary>
        public Dictionary<string, string> Headers
        {
            get { return _headers; }
        }

        /// <summary>
        /// 添加响应头
        /// </summary>
        /// <param name="headerName">响应头名称</param>
        /// <param name="value">头值</param>
        /// <exception cref="ArgumentNullException">响应头名称等于null将抛出异常</exception>
        public void AddHeader(string headerName, string value)
        {
            if (headerName == null)
            {
                throw new ArgumentNullException(nameof(headerName));
            }

            this._headers[headerName] = value;
        }

        private List<HeaderItem> _extendHeaders = null;
        /// <summary>
        /// 响应扩展头部-用于头中的重复项
        /// </summary>
        public List<HeaderItem> ExtendHeaders
        {
            get { return _extendHeaders; }
        }

        /// <summary>
        /// 添加响扩展应头
        /// </summary>
        /// <param name="headerItem">http响应头扩展项</param>
        /// <exception cref="ArgumentNullException">响应头名称等于null将抛出异常</exception>
        public void AddExtendHeader(HeaderItem headerItem)
        {
            if (headerItem == null)
            {
                throw new ArgumentNullException(nameof(headerItem));
            }

            if (this._extendHeaders == null)
            {
                this._extendHeaders = new List<HeaderItem>();
            }
            this._extendHeaders.Add(headerItem);
        }



        /// <summary>
        /// 文本编码
        /// </summary>
        public Encoding TextEncoding { get; set; }

        private DataSource _data = null;
        /// <summary>
        /// 响应正文数据
        /// </summary>
        public DataSource Data
        {
            get { return _data; }
            set { _data = value; }
        }

        private List<HttpRequestRange> _requestRangeList = null;
        /// <summary>
        /// 请求范围
        /// </summary>
        public List<HttpRequestRange> RequestRangeList
        {
            get { return _requestRangeList; }
            set { _requestRangeList = value; }
        }

        private int _chunkSize = WebConstnats.RES_PART_CONTENT_MAX_SIZE;
        /// <summary>
        /// 分块发送数据大小,默认WebConstnats.RES_PART_CONTENT_MAX_SIZE值100MB
        /// </summary>
        public int ChunkSize
        {
            get { return _chunkSize; }
            set { _chunkSize = value; }
        }


        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="connection">http连接</param>
        public HttpResponse(HttpConnection connection)
            : this(connection, new Dictionary<string, string>())
        {

        }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="connection">http连接</param>
        /// <param name="headers">http请求头集合</param>
        public HttpResponse(HttpConnection connection, Dictionary<string, string> headers)
            : base()
        {
            if (connection == null)
            {
                throw new ArgumentNullException(nameof(connection));
            }

            if (headers == null)
            {
                throw new ArgumentNullException(nameof(headers));
            }

            this._connection = connection;
            this._headers = headers;
        }









        #region 设置响应数据
        private Encoding GetEncoding()
        {
            var encoding = this.TextEncoding;
            if (encoding == null)
            {
                encoding = Encoding.UTF8;
            }

            return encoding;
        }

        /// <summary>
        /// 设置二进制内容
        /// </summary>
        /// <param name="buffer">内容buffer</param>
        public void SetBytes(byte[] buffer)
        {
            this._data = new DataSource(buffer);
            this._headers[HttpResponseHeaders.ContentType] = HttpContentTypes.STREAM;
        }

        /// <summary>
        /// 设置二进制内容
        /// </summary>
        /// <param name="contentType">http响应内容mime类型</param>
        /// <param name="buffer">内容buffer</param>
        public void SetBytes(string contentType, byte[] buffer)
        {
            this._data = new DataSource(buffer);
            this._headers[HttpResponseHeaders.ContentType] = contentType;
        }

        /// <summary>
        /// 设置文本内容
        /// </summary>
        /// <param name="contentType">内容类型</param>
        /// <param name="text">文本</param>
        public void SetTextContent(string contentType, string text)
        {
            var encoding = this.GetEncoding();
            if (text == null)
            {
                text = string.Empty;
            }

            this._data = new DataSource(encoding.GetBytes(text));
            this._headers[HttpResponseHeaders.ContentType] = $"{contentType}; {WebConstnats.CHARSET}={encoding.WebName}";
        }

        /// <summary>
        /// 设置文本内容
        /// </summary>
        /// <param name="text">文本</param>
        public void SetText(string text)
        {
            this.SetTextContent(HttpContentTypes.TEXT, text);
        }

        /// <summary>
        /// 设置xml内容
        /// </summary>
        /// <param name="xmlStr">xml字符串</param>
        public void SetXml(string xmlStr)
        {
            this.SetTextContent(HttpContentTypes.XML, xmlStr);
        }

        /// <summary>
        /// 设置json内容
        /// </summary>
        /// <param name="json">json</param>
        public void SetJSON(string json)
        {
            this.SetTextContent(HttpContentTypes.JSON, json);
        }

        /// <summary>
        /// 设置文件
        /// </summary>
        /// <param name="filePath">文件路径</param>
        /// <param name="offset">数据起始偏移位置,小于等于0从头开始</param>
        /// <param name="length">数据长度，小于0到结尾</param>
        public void SetFile(string filePath, long offset = -1, long length = -1)
        {
            if (!File.Exists(filePath))
            {
                this.StatusCode = HttpStatusCodes.NotFound;
                return;
            }

            this._data = new DataSource(filePath, offset, length);
            string extension = Path.GetExtension(filePath);
            this._headers[HttpResponseHeaders.ContentType] = HttpContentTypes.GetMimeMapping(extension);
        }
        #endregion
    }
}
